﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using UniCT.LinkShareWpf.Interface;
using System.Collections;
using System.Reflection;
using System.ComponentModel;

namespace UniCT.LinkShareWpf.Interface 
{
    public class Filter : INotifyPropertyChanged
    {
        string title;
        string director;
        string cast;
        EnumLanguage language;
        string type;
        string rating;
        string episodeN;
        string seasonN;
        
        public String Director
        {
            get { return this.director; }
            set
            {
                if (value != this.director)
                {
                    this.director = value;
                    this.OnPropertyChanged("Director");
                }
            }
        }
        public String Title
        {
            get { return this.title; }
            set
            {
                if (value != this.title)
                {
                    this.title = value;
                    this.OnPropertyChanged("Title");
                }
            }
        }
        public EnumLanguage Language
        {
            get { return this.language; }
            set
            {
                if (value != this.language)
                {
                    this.language = value;
                    this.OnPropertyChanged("Language");
                }
            }
        }
        public String Cast
        {
            get { return this.cast; }
            set
            {
                this.cast = value;
                this.OnPropertyChanged("Cast");
            }
        }
        public String Type
        {
            get { return this.type; }
            set
            {
                if (value != this.type)
                {
                    this.type = value;
                    this.OnPropertyChanged("Type");
                }
            }
        }
        public String Rating
        {
            get { return this.rating; }
            set
            {
                if (value != this.rating)
                {
                    this.rating = value;
                    this.OnPropertyChanged("Rating");
                }
            }
        }
        public String EpisodeN
        {
            get { return this.episodeN; }
            set
            {
                if (value != this.episodeN)
                {
                    this.episodeN = value;
                    this.OnPropertyChanged("EpisodeN");
                }
            }
        }
        public String SeasonN
        {
            get {  return this.seasonN; }
            set
            {
                if (value != this.seasonN)
                {
                   
                    this.seasonN = value;
                    this.OnPropertyChanged("SeasonN");
                }
            }
        }

        static char[] separators = { ' ', ',' };

        public Filter()
        {
            reset();
        }
        public void reset()
        {
            Title = String.Empty;
            Director = String.Empty;
             Cast = String.Empty;
             Language = EnumLanguage.Italiano;
             Type = "allRButton";
             Rating = "allRatRButton";
             episodeN = "All";
             seasonN = "All";

        }
        public ObservableCollection<Resource> filterResources(ObservableCollection<Resource> myList)
        {
            ObservableCollection<Resource> filteredList = new ObservableCollection<Resource>();
            Hashtable filterList = new Hashtable();

            if (!String.IsNullOrEmpty(this.title))
                filterList.Add("Title", this.title);
            if (!String.IsNullOrEmpty(this.director))
                filterList.Add("Director", this.director);
            if (!String.IsNullOrEmpty(this.cast))
                filterList.Add("Cast", this.cast);


            foreach (Resource res in myList)
            {
                bool check2 = false;
                // In base ai criteri di Director,Cast e Titolo
                
                # region ricercainbaseai3criteri
                foreach (string filter in filterList.Keys.Cast<string>())
                {

                    // Filter: Contiene il nome del campo da filtrare
                    // Attribtute: è il valore relativo al campo
                    // ottimizzazione filtro:
                    // Inquesto modo appena c'è anche un campo che non coincide esce e non controlla più il resto

                    string attribute = res.CInfo.GetType().GetProperty(filter).GetValue(res.CInfo, null).ToString();

                    //Console.WriteLine("NOME ATTRIBUTO: " + filter + " || VALORE ATTRIBUTO: " + attribute);  //OK

                    string[] partsOfString = filterList[filter].ToString().ToUpper().Split(separators);

                    foreach (string partOfString in partsOfString)
                    {
                        //Console.WriteLine(partOfString + "    " + attribute.ToUpper());
                        if (!attribute.ToUpper().Contains(partOfString))
                        {
                            check2 = true;
                            break;
                        }
                    }
                    if (check2)
                        break;


                }
                # endregion

                bool check3 = false;
                if (!check2)

                    #region Filtro in base alla lingue e alla qualità

                    //aggiungo i controlli in cascata per i campi obbligatori del filtro
                    if (language.Equals(res.CInfo.Language))
                    {
                        //Console.WriteLine("LINGUAGGIO: " + language + "-" + res.CInfo.Language);
                        #region ricercainbasealrating

                        if (this.rating.Equals("highRatRButton"))
                        {
                            if (res.Rating >= 0.8)
                                    check3 = true;
                        }
                        else if (this.rating.Equals("lowRatRButton"))
                        {
                            if (res.Rating < 0.8)
                                    check3 = true;
                        }
                        else
                            check3 = true;



                        #endregion





                    }
                    #endregion


                if (check3)
                {

                    #region Filtro in base alla tiplogia della Risorsa

                    // Tutte le risorse
                    if (this.type.Equals("allRButton"))
                        filteredList.Add(res);
                    // Solamente i film, aggiungiamo quindi solo le risorse
                    // che non hanno come CINFO una serieTV
                    else if (this.type.Equals("filmRButton"))
                    {
                        if (!(res.CInfo.GetType() == typeof(ContentInfoTVS)))
                            filteredList.Add(res);
                    }

                    // Se si cerca solamente SerieTv

                    else if (this.type.Equals("tvseriesRButton") && res.CInfo.GetType() == typeof(ContentInfoTVS))
                        //Sono nel caso in cui sto cercando una serie TV
                    {
                        if (this.seasonN.Equals("All"))
                        {
                            if (this.episodeN.Equals("All"))
                                filteredList.Add(res);
                            else
                                if (this.episodeN.Equals((res.CInfo as ContentInfoTVS).EpisodNumber.ToString()))
                                    filteredList.Add(res);
                        }
                        else
                            if (this.seasonN.Equals((res.CInfo as ContentInfoTVS).SeasonNumber.ToString()))
                            {
                                if (this.episodeN.Equals("All"))
                                    filteredList.Add(res);
                                else
                                    if (this.episodeN.Equals((res.CInfo as ContentInfoTVS).EpisodNumber.ToString()))
                                        filteredList.Add(res);
                            }
                    }
                    //{
                    //    //Console.WriteLine("Filtro.seasonN: " + this.seasonN + " Risorsa.Season " + (res.CInfo as ContentInfoTVS).SeasonNumber);
                    //    //Console.WriteLine("Filtro.episodeN: " + this.episodeN + " Risorsa.Episode " + (res.CInfo as ContentInfoTVS).EpisodNumber);
                        
                    //    //Se ho cercato con un determinato numero di stagione e questo numero è uguale a quello della risorsa in esame...
                    //    if (!(this.seasonN.Equals("All")) && this.seasonN.Equals((res.CInfo as ContentInfoTVS).SeasonNumber.ToString()))
                    //    {

                    //        //... se ho cercato con un determinato numero di episodo ...
                    //        if (!(this.episodeN.Equals("All")))
                    //        {
                    //            //... se il numero di episodio è uguale a quello della risorsa
                    //            if (this.episodeN.Equals((res.CInfo as ContentInfoTVS).EpisodNumber.ToString()))
                    //                // aggiungo la risorsa
                    //                filteredList.Add(res);

                                
                    //        }
                    //        else
                    //            //... sono nella condizione di stagione specifica ed episodio generico, quindi aggiungo l'episodio
                    //            filteredList.Add(res);


                    //    }
                    //    else
                    //        //Se ho cercato con un determinato numero di episodio ma senza una stagione specifica
                    //        if (!(this.episodeN.Equals("All")) && this.SeasonN.Equals("All"))
                    //        {
                    //                //... se il numero di episodio è uguale a quello della risorsa
                    //                if (this.episodeN.Equals((res.CInfo as ContentInfoTVS).EpisodNumber.ToString()))
                    //                    // aggiungo la risorsa
                    //                    filteredList.Add(res);
                    //        }
                    //        else
                    //            //nel caso restante, ho cercato senza stagione e numero di episodio specifico,
                    //            //quindi aggiungo comunque la risorsa
                    //            filteredList.Add(res);





                    //        }
                    }
                    #endregion
                   
                 }
             
            return filteredList;
        }
        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }

}
